package com.dd.ms.storage.web.service.internal;

import com.dd.ms.storage.api.StorageRpcApi;
import com.dd.ms.storage.web.pojo.domain.CosProperties;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.transfer.Download;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.Upload;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author liuxianmeng
 * @CreateTime 2025/6/23 0:59
 * @Description DataObjectServiceImpl
 */
@Slf4j
@Service
@RequiredArgsConstructor
@DubboService(interfaceClass = StorageRpcApi.class, group = "DUBBO_DD_MS_STORAGE", version = "1.0")
public class CosServiceImpl implements StorageRpcApi {

    private final COSClient cosClient;
    private final CosProperties cosProperties;

    // 创建异步传输管理器
    private TransferManager createTransferManager() {
        ExecutorService threadPool = Executors.newFixedThreadPool(4);
        return new TransferManager(cosClient, threadPool);
    }

    /**
     * 上传文件
     *
     * @param file 上传的文件对象
     * @return 文件访问URL
     */
    public String upload(MultipartFile file, String appName) throws IOException {
        String key = null;
        InputStream inputStream = null;
        TransferManager transferManager = null;

        try {
            // 1. 生成带年月目录的COS对象键（无需提前创建目录）
            String originalFilename = file.getOriginalFilename();
            String fileExtensionName = originalFilename.substring(originalFilename.lastIndexOf("."));
            String yearMonth = DateTimeFormatter.ofPattern("yyyyMM").format(LocalDate.now());
            // 1.2 根据appName生成（选择）顶层文件夹名
            String topDirName = "TEST";
            if(appName != null) {
                topDirName = appName;
            }
            // 1.2.5 文件Path：顶层文件夹名/年月/randomUUID.文件拓展名
            key = topDirName + "/" + yearMonth + "/" + UUID.randomUUID() + fileExtensionName; // COS自动处理路径

            // 2. 执行上传（路径不存在时会自动"创建"）
            transferManager = createTransferManager();
            inputStream = file.getInputStream();

            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(file.getSize());

            Upload upload = transferManager.upload(
                    cosProperties.getBucketName(),
                    key, // 包含完整路径的键名
                    inputStream,
                    metadata
            );
            upload.waitForUploadResult();

            return getFileUrl(key);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            // 3. 资源清理
            if (transferManager != null) transferManager.shutdownNow();
            if (inputStream != null) inputStream.close();
        }
    }

    /**
     * 下载文件到本地
     *
     * @param key 文件在COS中的路径
     * @param localFilePath 本地保存路径
     */
    public void downloadFile(String key, String localFilePath) {
        if (localFilePath == null) {
            localFilePath = "E:\\BaiduNetdiskDownload";
        }
        TransferManager transferManager = createTransferManager();
        try {
            File localFile = new File(localFilePath);
            Download download = transferManager.download(
                    cosProperties.getBucketName(),
                    key,
                    localFile
            );
            download.waitForCompletion(); // 等待下载完成
        } catch (CosClientException | InterruptedException e) {
            throw new RuntimeException("文件下载失败: " + e.getMessage(), e);
        } finally {
            transferManager.shutdownNow();
        }
    }

    /**
     * 获取文件临时访问URL（有效期7天）
     *
     * @param key 文件在COS中的路径
     * @return 带签名的临时URL
     */
    @Override
    public String getFileUrl(String key) {
        // 设置URL过期时间（7天）
        Date expiration = new Date(System.currentTimeMillis() + 7 * 24 * 3600 * 1000);

        // 生成预签名URL
        URL url = cosClient.generatePresignedUrl(
                cosProperties.getBucketName(),
                key,
                expiration
        );
        return url.toString();
    }

    /**
     * 删除文件
     * @param key 文件在COS中的路径 如："TEST/202506/d4f9dad1-333d-4971-bc14-6863af211b5a.png"
     */
    public void delete(String key) {
        try {
            cosClient.deleteObject(cosProperties.getBucketName(), key);
        } catch (CosClientException e) {
            throw new RuntimeException("文件删除失败: " + e.getMessage(), e);
        }
    }
}
